#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "UdpStream.h"

#pragma comment(lib, "ws2_32.lib")

#ifndef MAKEWORD
#define MAKEWORD(x, y) (x+y)
#endif

using namespace std;
using namespace vs::net;


const int SERVER_PORT = 12345;
const int CLIENT_PORT = 12346;


void UdpServer()
{
	InternetAddress clientAddress(CLIENT_PORT, "127.0.0.1");
	UdpStream server(SERVER_PORT, "localhost");

	while (1)
	{
		char buf[1024] = "";
		InternetAddress client;
		int ret = server.RecvFrom(buf, 1024, 0, &client);
		if (ret == SOCKET_ERROR)
		{
			printf("recvfrom failed[%d]\n", GetNetError());
			break;
		}
		else
		{
			char clientName[100] = "";
			client.ToString(clientName, 100);
			printf("received messages[%s] from [%s]\n", buf, clientName);

			if (server.SendTo("msg from server", strlen("msg from server"), 0, &clientAddress) != SOCKET_ERROR)
			{
				printf("send message ok\n");
			}
			else
			{
				printf("send message error[%d]\n", GetNetError());
				break;
			}
		}
	}
}


void UdpClient()
{
	InternetAddress serverAddress(SERVER_PORT, "127.0.0.1");
	UdpStream client(CLIENT_PORT, "127.0.0.1");

	while (1)
	{
		char message[] = "message from client";
		if (client.SendTo(message, strlen(message), 0, &serverAddress) != SOCKET_ERROR)
		{
			printf("send message ok\n");
		}
		else
		{
			printf("send message error[%d]\n", GetNetError());
			break;
		}

		char buf[1024] = "";
		InternetAddress clientAddr;
		int ret = client.RecvFrom(buf, 1024, 0, &clientAddr);
		if (ret == SOCKET_ERROR)
		{
			printf("recvfrom failed[%d]\n", GetNetError());
			break;
		}
		else
		{
			char clientName[100] = "";
			clientAddr.ToString(clientName, 100);
			printf("received messages[%s] from [%s]\n", buf, clientName);
		}

#ifdef WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
	}
}


int main(int argc, char **argv)
{
	if (argc != 2)
	{
		printf("%s server|client\n", argv[0]);
		return 0;
	}

	NetInitializer init(MAKEWORD(2, 2));
	if (!init.IsNetworkReady())
	{
		printf("init network error\n");
		return -1;
	}

	if (strcmp(argv[1], "server") == 0)
	{
		UdpServer();
	}
	else
	{
		UdpClient();
	}


	return 0;
}

